package persistence

import (
	"context"

	"Data-API-MCP/backend/internal/domain/entity"
	"database/sql"
	"fmt"
	"time"
)

// StatisticsRepository 统计仓库实现
type StatisticsRepository struct {
	db *sql.DB
}

// NewStatisticsRepository 创建统计仓库
func NewStatisticsRepository(db *sql.DB) *StatisticsRepository {
	return &StatisticsRepository{db: db}
}

// RecordAPICall 记录API调用
func (r *StatisticsRepository) RecordAPICall(ctx context.Context, call *entity.APICall) error {
	query := `
		INSERT INTO api_calls (
			id, api_id, version, caller, request_ip, request_time,
			params, result, status, error_msg, duration, created_at, updated_at
		) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
	`
	_, err := r.db.ExecContext(ctx, query,
		call.ID,
		call.APIID,
		call.Version,
		call.Caller,
		call.RequestIP,
		call.RequestTime,
		call.Params,
		call.Result,
		call.Status,
		call.ErrorMsg,
		call.Duration,
		call.CreatedAt,
		call.UpdatedAt,
	)
	return err
}

// GetAPICallStats 获取API调用统计
func (r *StatisticsRepository) GetAPICallStats(ctx context.Context, startTime time.Time) (map[string]interface{}, error) {
	// 获取每日统计
	dailyQuery := `
		SELECT 
			DATE(request_time) as date,
			COUNT(*) as total_calls,
			SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success_calls,
			SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as error_calls,
			AVG(duration) as avg_duration
		FROM api_calls
		WHERE request_time >= ?
		GROUP BY DATE(request_time)
		ORDER BY date
	`
	rows, err := r.db.QueryContext(ctx, dailyQuery, startTime)
	if err != nil {
		return nil, fmt.Errorf("查询每日统计失败: %v", err)
	}
	defer rows.Close()

	dailyStats := make([]map[string]interface{}, 0)
	for rows.Next() {
		var date string
		var totalCalls, successCalls, errorCalls int
		var avgDuration float64

		if err := rows.Scan(&date, &totalCalls, &successCalls, &errorCalls, &avgDuration); err != nil {
			return nil, fmt.Errorf("扫描每日统计数据失败: %v", err)
		}

		successRate := 0.0
		if totalCalls > 0 {
			successRate = float64(successCalls) / float64(totalCalls) * 100
		}

		dailyStats = append(dailyStats, map[string]interface{}{
			"date":          date,
			"total_calls":   totalCalls,
			"success_calls": successCalls,
			"error_calls":   errorCalls,
			"avg_duration":  avgDuration,
			"success_rate":  successRate,
		})
	}

	// 获取总体统计
	totalQuery := `
		SELECT 
			COUNT(*) as total_calls,
			SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success_calls,
			SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as error_calls,
			AVG(duration) as avg_duration
		FROM api_calls
		WHERE request_time >= ?
	`
	var totalStats struct {
		TotalCalls   int     `db:"total_calls"`
		SuccessCalls int     `db:"success_calls"`
		ErrorCalls   int     `db:"error_calls"`
		AvgDuration  float64 `db:"avg_duration"`
	}

	err = r.db.QueryRowContext(ctx, totalQuery, startTime).Scan(
		&totalStats.TotalCalls,
		&totalStats.SuccessCalls,
		&totalStats.ErrorCalls,
		&totalStats.AvgDuration,
	)
	if err != nil {
		return nil, fmt.Errorf("查询总体统计失败: %v", err)
	}

	successRate := 0.0
	if totalStats.TotalCalls > 0 {
		successRate = float64(totalStats.SuccessCalls) / float64(totalStats.TotalCalls) * 100
	}

	return map[string]interface{}{
		"daily_stats": dailyStats,
		"total_stats": map[string]interface{}{
			"total_calls":   totalStats.TotalCalls,
			"success_calls": totalStats.SuccessCalls,
			"error_calls":   totalStats.ErrorCalls,
			"avg_duration":  totalStats.AvgDuration,
			"success_rate":  successRate,
		},
	}, nil
}

// GetAPICallDetail 获取API调用详情
func (r *StatisticsRepository) GetAPICallDetail(ctx context.Context, id string) (*entity.APICall, error) {
	query := `
		SELECT 
			id, api_id, version, caller, request_ip, request_time,
			params, result, status, error_msg, duration, created_at, updated_at
		FROM api_calls
		WHERE id = ?
	`
	var call entity.APICall
	err := r.db.QueryRowContext(ctx, query, id).Scan(
		&call.ID,
		&call.APIID,
		&call.Version,
		&call.Caller,
		&call.RequestIP,
		&call.RequestTime,
		&call.Params,
		&call.Result,
		&call.Status,
		&call.ErrorMsg,
		&call.Duration,
		&call.CreatedAt,
		&call.UpdatedAt,
	)
	if err != nil {
		return nil, fmt.Errorf("查询API调用详情失败: %v", err)
	}
	return &call, nil
}

// GetAPIErrorStats 获取API错误统计
func (r *StatisticsRepository) GetAPIErrorStats(ctx context.Context, startTime time.Time) (map[string]interface{}, error) {
	query := `
		SELECT 
			error_msg,
			COUNT(*) as error_count
		FROM api_calls
		WHERE request_time >= ? AND status = 0
		GROUP BY error_msg
		ORDER BY error_count DESC
	`
	rows, err := r.db.QueryContext(ctx, query, startTime)
	if err != nil {
		return nil, fmt.Errorf("查询API错误统计失败: %v", err)
	}
	defer rows.Close()

	errorStats := make([]map[string]interface{}, 0)
	for rows.Next() {
		var errorMsg string
		var errorCount int
		if err := rows.Scan(&errorMsg, &errorCount); err != nil {
			return nil, fmt.Errorf("扫描API错误统计数据失败: %v", err)
		}

		errorStats = append(errorStats, map[string]interface{}{
			"error_msg":   errorMsg,
			"error_count": errorCount,
		})
	}

	return map[string]interface{}{
		"error_stats": errorStats,
	}, nil
}

// GetAPIPerformance 获取API性能统计
func (r *StatisticsRepository) GetAPIPerformance(ctx context.Context, startTime time.Time) (map[string]interface{}, error) {
	query := `
		SELECT 
			AVG(duration) as avg_duration,
			MAX(duration) as max_duration,
			MIN(duration) as min_duration,
			PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration) as p95_duration,
			PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY duration) as p99_duration
		FROM api_calls
		WHERE request_time >= ?
	`
	var stats struct {
		AvgDuration float64 `db:"avg_duration"`
		MaxDuration int64   `db:"max_duration"`
		MinDuration int64   `db:"min_duration"`
		P95Duration float64 `db:"p95_duration"`
		P99Duration float64 `db:"p99_duration"`
	}

	err := r.db.QueryRowContext(ctx, query, startTime).Scan(
		&stats.AvgDuration,
		&stats.MaxDuration,
		&stats.MinDuration,
		&stats.P95Duration,
		&stats.P99Duration,
	)
	if err != nil {
		return nil, fmt.Errorf("查询API性能统计失败: %v", err)
	}

	return map[string]interface{}{
		"avg_duration": stats.AvgDuration,
		"max_duration": stats.MaxDuration,
		"min_duration": stats.MinDuration,
		"p95_duration": stats.P95Duration,
		"p99_duration": stats.P99Duration,
	}, nil
}

// GetAPICallLogs 获取API调用日志
func (r *StatisticsRepository) GetAPICallLogs(ctx context.Context, apiID string, startTime, endTime time.Time) ([]*entity.APICall, error) {
	query := `
		SELECT 
			id, api_id, version, caller, request_ip, request_time,
			params, result, status, error_msg, duration, created_at, updated_at
		FROM api_calls
		WHERE api_id = ? AND request_time BETWEEN ? AND ?
		ORDER BY request_time DESC
	`
	rows, err := r.db.QueryContext(ctx, query, apiID, startTime, endTime)
	if err != nil {
		return nil, fmt.Errorf("查询API调用日志失败: %v", err)
	}
	defer rows.Close()

	calls := make([]*entity.APICall, 0)
	for rows.Next() {
		var call entity.APICall
		if err := rows.Scan(
			&call.ID,
			&call.APIID,
			&call.Version,
			&call.Caller,
			&call.RequestIP,
			&call.RequestTime,
			&call.Params,
			&call.Result,
			&call.Status,
			&call.ErrorMsg,
			&call.Duration,
			&call.CreatedAt,
			&call.UpdatedAt,
		); err != nil {
			return nil, fmt.Errorf("扫描API调用日志数据失败: %v", err)
		}
		calls = append(calls, &call)
	}

	return calls, nil
}

// GetDatabaseStats 获取数据库连接统计
func (r *StatisticsRepository) GetDatabaseStats(ctx context.Context) (map[string]interface{}, error) {
	// 获取数据库连接总数
	totalQuery := `
		SELECT 
			COUNT(*) as total_connections,
			SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_connections,
			SUM(CASE WHEN status = 'inactive' THEN 1 ELSE 0 END) as inactive_connections
		FROM database_connections
	`
	var totalStats struct {
		TotalConnections    int `db:"total_connections"`
		ActiveConnections   int `db:"active_connections"`
		InactiveConnections int `db:"inactive_connections"`
	}

	err := r.db.QueryRowContext(ctx, totalQuery).Scan(
		&totalStats.TotalConnections,
		&totalStats.ActiveConnections,
		&totalStats.InactiveConnections,
	)
	if err != nil {
		return nil, fmt.Errorf("查询数据库连接总数失败: %v", err)
	}

	// 获取按数据库类型的统计
	typeQuery := `
		SELECT 
			db_type,
			COUNT(*) as count,
			SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_count
		FROM database_connections
		GROUP BY db_type
	`
	rows, err := r.db.QueryContext(ctx, typeQuery)
	if err != nil {
		return nil, fmt.Errorf("查询数据库类型统计失败: %v", err)
	}
	defer rows.Close()

	typeStats := make([]map[string]interface{}, 0)
	for rows.Next() {
		var dbType string
		var count, activeCount int
		if err := rows.Scan(&dbType, &count, &activeCount); err != nil {
			return nil, fmt.Errorf("扫描数据库类型统计数据失败: %v", err)
		}

		typeStats = append(typeStats, map[string]interface{}{
			"db_type":      dbType,
			"total_count":  count,
			"active_count": activeCount,
		})
	}

	return map[string]interface{}{
		"total_stats": map[string]interface{}{
			"total_connections":    totalStats.TotalConnections,
			"active_connections":   totalStats.ActiveConnections,
			"inactive_connections": totalStats.InactiveConnections,
		},
		"type_stats": typeStats,
	}, nil
}

// GetServiceStats 获取服务统计
func (r *StatisticsRepository) GetServiceStats(ctx context.Context, serviceID string) (*entity.ServiceStats, error) {
	query := `
		SELECT 
			id, service_id, call_count, success_count, error_count,
			avg_response_time, last_called_at, created_at, updated_at
		FROM service_stats
		WHERE service_id = ?
	`
	var stats entity.ServiceStats
	err := r.db.QueryRowContext(ctx, query, serviceID).Scan(
		&stats.ID,
		&stats.ServiceID,
		&stats.CallCount,
		&stats.SuccessCount,
		&stats.ErrorCount,
		&stats.AvgResponseTime,
		&stats.LastCalledAt,
		&stats.CreatedAt,
		&stats.UpdatedAt,
	)
	if err != nil {
		return nil, fmt.Errorf("查询服务统计失败: %v", err)
	}
	return &stats, nil
}

// GetServiceHealth 获取服务健康状态
func (r *StatisticsRepository) GetServiceHealth(ctx context.Context, serviceID string) (map[string]interface{}, error) {
	// 获取最近24小时的调用统计
	query := `
		SELECT 
			COUNT(*) as total_calls,
			SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as success_calls,
			SUM(CASE WHEN status = 'error' THEN 1 ELSE 0 END) as error_calls,
			AVG(response_time) as avg_response_time,
			MAX(created_at) as last_called_at
		FROM service_call_logs
		WHERE service_id = ? AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
	`
	var stats struct {
		TotalCalls      int       `db:"total_calls"`
		SuccessCalls    int       `db:"success_calls"`
		ErrorCalls      int       `db:"error_calls"`
		AvgResponseTime float64   `db:"avg_response_time"`
		LastCalledAt    time.Time `db:"last_called_at"`
	}

	err := r.db.QueryRowContext(ctx, query, serviceID).Scan(
		&stats.TotalCalls,
		&stats.SuccessCalls,
		&stats.ErrorCalls,
		&stats.AvgResponseTime,
		&stats.LastCalledAt,
	)
	if err != nil {
		return nil, fmt.Errorf("查询服务健康状态失败: %v", err)
	}

	successRate := 0.0
	if stats.TotalCalls > 0 {
		successRate = float64(stats.SuccessCalls) / float64(stats.TotalCalls) * 100
	}

	return map[string]interface{}{
		"total_calls":       stats.TotalCalls,
		"success_calls":     stats.SuccessCalls,
		"error_calls":       stats.ErrorCalls,
		"avg_response_time": stats.AvgResponseTime,
		"success_rate":      successRate,
		"last_called_at":    stats.LastCalledAt,
		"health_status":     successRate >= 95.0, // 成功率大于95%视为健康
	}, nil
}

// GetTopServices 获取热门服务
func (r *StatisticsRepository) GetTopServices(ctx context.Context, limit int) ([]*entity.ServiceStats, error) {
	query := `
		SELECT 
			id, service_id, call_count, success_count, error_count,
			avg_response_time, last_called_at, created_at, updated_at
		FROM service_stats
		ORDER BY call_count DESC
		LIMIT ?
	`
	rows, err := r.db.QueryContext(ctx, query, limit)
	if err != nil {
		return nil, fmt.Errorf("查询热门服务失败: %v", err)
	}
	defer rows.Close()

	services := make([]*entity.ServiceStats, 0)
	for rows.Next() {
		var stats entity.ServiceStats
		if err := rows.Scan(
			&stats.ID,
			&stats.ServiceID,
			&stats.CallCount,
			&stats.SuccessCount,
			&stats.ErrorCount,
			&stats.AvgResponseTime,
			&stats.LastCalledAt,
			&stats.CreatedAt,
			&stats.UpdatedAt,
		); err != nil {
			return nil, fmt.Errorf("扫描热门服务数据失败: %v", err)
		}
		services = append(services, &stats)
	}

	return services, nil
}

// RecordDatabaseConnectionStats 记录数据库连接统计
func (r *StatisticsRepository) RecordDatabaseConnectionStats(ctx context.Context, stats *entity.DatabaseConnectionStats) error {
	query := `
		INSERT INTO database_connections (
			id, name, db_type, status, created_at, updated_at,
			last_used_at, connection_count, error_count, avg_response_time
		) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
		ON DUPLICATE KEY UPDATE
			status = VALUES(status),
			updated_at = VALUES(updated_at),
			last_used_at = VALUES(last_used_at),
			connection_count = VALUES(connection_count),
			error_count = VALUES(error_count),
			avg_response_time = VALUES(avg_response_time)
	`
	_, err := r.db.ExecContext(ctx, query,
		stats.ID,
		stats.Name,
		stats.DBType,
		stats.Status,
		stats.CreatedAt,
		stats.UpdatedAt,
		stats.LastUsedAt,
		stats.ConnectionCount,
		stats.ErrorCount,
		stats.AvgResponseTime,
	)
	return err
}

// GetDatabaseConnectionStats 获取数据库连接统计
func (r *StatisticsRepository) GetDatabaseConnectionStats(ctx context.Context, dbType string) ([]*entity.DatabaseConnectionStats, error) {
	query := `
		SELECT 
			id, name, db_type, status, created_at, updated_at,
			last_used_at, connection_count, error_count, avg_response_time
		FROM database_connections
		WHERE db_type = ?
		ORDER BY created_at DESC
	`
	rows, err := r.db.QueryContext(ctx, query, dbType)
	if err != nil {
		return nil, fmt.Errorf("查询数据库连接统计失败: %v", err)
	}
	defer rows.Close()

	stats := make([]*entity.DatabaseConnectionStats, 0)
	for rows.Next() {
		var s entity.DatabaseConnectionStats
		if err := rows.Scan(
			&s.ID,
			&s.Name,
			&s.DBType,
			&s.Status,
			&s.CreatedAt,
			&s.UpdatedAt,
			&s.LastUsedAt,
			&s.ConnectionCount,
			&s.ErrorCount,
			&s.AvgResponseTime,
		); err != nil {
			return nil, fmt.Errorf("扫描数据库连接统计数据失败: %v", err)
		}
		stats = append(stats, &s)
	}

	return stats, nil
}

// RecordServiceCallLog 记录服务调用日志
func (r *StatisticsRepository) RecordServiceCallLog(ctx context.Context, log *entity.ServiceCallLog) error {
	query := `
		INSERT INTO service_call_logs (
			id, service_id, created_at, status, response_time,
			error_message, request_data, response_data
		) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
	`
	_, err := r.db.ExecContext(ctx, query,
		log.ID,
		log.ServiceID,
		log.CreatedAt,
		log.Status,
		log.ResponseData,
		log.ErrorMessage,
		log.RequestData,
		log.ResponseData,
	)
	return err
}

// GetServiceCallLogs 获取服务调用日志
func (r *StatisticsRepository) GetServiceCallLogs(ctx context.Context, serviceID string, startTime, endTime time.Time) ([]*entity.ServiceCallLog, error) {
	query := `
		SELECT 
			id, service_id, created_at, status, response_time,
			error_message, request_data, response_data
		FROM service_call_logs
		WHERE service_id = ? AND created_at BETWEEN ? AND ?
		ORDER BY created_at DESC
	`
	rows, err := r.db.QueryContext(ctx, query, serviceID, startTime, endTime)
	if err != nil {
		return nil, fmt.Errorf("查询服务调用日志失败: %v", err)
	}
	defer rows.Close()

	logs := make([]*entity.ServiceCallLog, 0)
	for rows.Next() {
		var log entity.ServiceCallLog
		if err := rows.Scan(
			&log.ID,
			&log.ServiceID,
			&log.CreatedAt,
			&log.Status,
			&log.Duration,
			&log.ErrorMessage,
			&log.RequestData,
			&log.ResponseData,
		); err != nil {
			return nil, fmt.Errorf("扫描服务调用日志数据失败: %v", err)
		}
		logs = append(logs, &log)
	}

	return logs, nil
}
